using System;
using UnityEditor;
using UnityEngine;
using System.Collections.Generic;
using System.Reflection;
using System.Linq;
using EntityKit.Runtime;
using Object = UnityEngine.Object;

namespace EntityKit.Editor
{
    [CustomEditor(typeof(EntityLauncher))]
    [CanEditMultipleObjects]
    public class SceneEntityLauncherInspector : UnityEditor.Editor
    {
        #region Fields

        private bool showEntities = true;
        private bool showRuntimeEntities = true;
        private bool showSceneEntities = true;
        private EntityLauncher launcher;
        
        // 样式定义
        private GUIStyle m_BoxStyle;
        private GUIStyle m_HeaderStyle;
        private GUIStyle m_FoldoutStyle;
        private GUIStyle m_SectionHeaderStyle;
        private GUIStyle m_LabelStyle;
        private GUIStyle m_ValueStyle;
        private GUIStyle m_ButtonStyle;
        private GUIStyle m_MiniLabelStyle;
        
        private const string FOLDOUT_OPEN_PREFIX = "▼ ";
        private const string FOLDOUT_CLOSED_PREFIX = "▶ ";

        #endregion

        #region Unity Lifecycle

        private void OnEnable()
        {
            launcher = (EntityLauncher)target;
        }

        public override void OnInspectorGUI()
        {
            InitStyles();
            
            DrawInitializationOpportunity();
            EditorGUILayout.Space();
            
            DrawDefaultEntitiesSection();
            DrawRuntimeEntitiesSection();
            DrawSceneEntitiesSection();
            
            EditorGUILayout.Space();
            DrawActionButtons();
        }

        #endregion
        
        #region Styles

        private void InitStyles()
        {
            if (m_BoxStyle == null)
            {
                m_BoxStyle = new GUIStyle(EditorStyles.helpBox);
                m_BoxStyle.padding = new RectOffset(10, 10, 10, 10);
                m_BoxStyle.margin = new RectOffset(0, 0, 5, 5);
            }

            if (m_HeaderStyle == null)
            {
                m_HeaderStyle = new GUIStyle(EditorStyles.largeLabel);
                m_HeaderStyle.fontStyle = FontStyle.Bold;
                m_HeaderStyle.fontSize = 16;
                m_HeaderStyle.margin = new RectOffset(0, 0, 5, 10);
                m_HeaderStyle.normal.textColor = EditorGUIUtility.isProSkin ? new Color(0.8f, 0.8f, 0.8f) : new Color(0.2f, 0.2f, 0.2f);
            }

            if (m_FoldoutStyle == null)
            {
                m_FoldoutStyle = new GUIStyle(EditorStyles.foldout);
                m_FoldoutStyle.fontStyle = FontStyle.Bold;
                m_FoldoutStyle.fontSize = 14;
                m_FoldoutStyle.margin = new RectOffset(0, 0, 5, 5);
            }

            if (m_SectionHeaderStyle == null)
            {
                m_SectionHeaderStyle = new GUIStyle(EditorStyles.boldLabel);
                m_SectionHeaderStyle.fontSize = 12;
                m_SectionHeaderStyle.margin = new RectOffset(0, 0, 5, 5);
                m_SectionHeaderStyle.normal.textColor = EditorGUIUtility.isProSkin ? new Color(0.7f, 0.85f, 1.0f) : new Color(0.1f, 0.3f, 0.6f);
            }

            if (m_LabelStyle == null)
            {
                m_LabelStyle = new GUIStyle(EditorStyles.label);
                m_LabelStyle.margin = new RectOffset(0, 0, 2, 2);
                m_LabelStyle.fontSize = 11;
                m_LabelStyle.normal.textColor = EditorGUIUtility.isProSkin ? Color.white : Color.black;
            }

            if (m_ValueStyle == null)
            {
                m_ValueStyle = new GUIStyle(EditorStyles.label);
                m_ValueStyle.margin = new RectOffset(0, 0, 2, 2);
                m_ValueStyle.fontSize = 11;
                m_ValueStyle.normal.textColor = EditorGUIUtility.isProSkin ? new Color(0.7f, 0.9f, 0.7f) : new Color(0.1f, 0.5f, 0.1f);
            }
            
            if (m_ButtonStyle == null)
            {
                m_ButtonStyle = new GUIStyle(GUI.skin.button);
                m_ButtonStyle.padding = new RectOffset(10, 10, 5, 5);
                m_ButtonStyle.fontSize = 11;
                m_ButtonStyle.normal.textColor = EditorGUIUtility.isProSkin ? Color.white : Color.black;
            }
            
            if (m_MiniLabelStyle == null)
            {
                m_MiniLabelStyle = new GUIStyle(EditorStyles.miniLabel);
                m_MiniLabelStyle.fontSize = 10;
                m_MiniLabelStyle.margin = new RectOffset(0, 0, 2, 2);
                m_MiniLabelStyle.normal.textColor = EditorGUIUtility.isProSkin ? new Color(0.7f, 0.7f, 0.7f) : new Color(0.3f, 0.3f, 0.3f);
            }
        }

        #endregion

        #region Sections

        private void DrawDefaultEntitiesSection()
        {
            GUILayout.BeginVertical(m_BoxStyle);
            showEntities = EditorGUILayout.Foldout(showEntities, 
                new GUIContent((showEntities ? FOLDOUT_OPEN_PREFIX : FOLDOUT_CLOSED_PREFIX) + "默认实体列表"), 
                true, m_FoldoutStyle);
            if (showEntities)
            {
                EditorGUI.indentLevel++;
                DrawDefaultEntitiesList();
                EditorGUI.indentLevel--;
            }
            GUILayout.EndVertical();
            EditorGUILayout.Space();
        }

        private void DrawRuntimeEntitiesSection()
        {
            if (Application.isPlaying)
            {
                GUILayout.BeginVertical(m_BoxStyle);
                showRuntimeEntities = EditorGUILayout.Foldout(showRuntimeEntities, 
                    new GUIContent((showRuntimeEntities ? FOLDOUT_OPEN_PREFIX : FOLDOUT_CLOSED_PREFIX) + "运行时实体列表"), 
                    true, m_FoldoutStyle);
                if (showRuntimeEntities)
                {
                    EditorGUI.indentLevel++;
                    DrawRuntimeEntitiesList();
                    EditorGUI.EndDisabledGroup();
                }
                GUILayout.EndVertical();
                EditorGUILayout.Space();
            }
        }

        private void DrawSceneEntitiesSection()
        {
            GUILayout.BeginVertical(m_BoxStyle);
            showSceneEntities = EditorGUILayout.Foldout(showSceneEntities, 
                new GUIContent((showSceneEntities ? FOLDOUT_OPEN_PREFIX : FOLDOUT_CLOSED_PREFIX) + "场景中所有实体"), 
                true, m_FoldoutStyle);
            if (showSceneEntities)
            {
                EditorGUI.indentLevel++;
                DrawSceneEntitiesList();
                EditorGUI.indentLevel--;
            }
            GUILayout.EndVertical();
            EditorGUILayout.Space();
        }

        #endregion

        #region Initialization Opportunity

        private void DrawInitializationOpportunity()
        {
            GUILayout.BeginVertical(m_BoxStyle);
            EditorGUILayout.LabelField("初始化设置", m_SectionHeaderStyle);
            
            var opportunityField = typeof(EntityLauncher).GetField("mInitializationOpportunity",
                BindingFlags.NonPublic | BindingFlags.Instance);
            
            if (opportunityField != null)
            {
                var currentValue = (EntityLauncher.InitializationOpportunity)opportunityField.GetValue(launcher);
                var newValue = (EntityLauncher.InitializationOpportunity)EditorGUILayout.EnumPopup("初始化时机", currentValue);

                if (newValue != currentValue)
                {
                    opportunityField.SetValue(launcher, newValue);
                    EditorUtility.SetDirty(target);
                }

                EditorGUILayout.HelpBox(
                    newValue == EntityLauncher.InitializationOpportunity.Auto
                        ? "自动模式: 场景启动时自动初始化所有实体"
                        : "自定义模式: 需要手动调用初始化方法", MessageType.Info);
            }
            GUILayout.EndVertical();
        }

        #endregion

        #region Default Entities List

        /// <summary>
        /// 绘制默认实体列表
        /// </summary>
        private void DrawDefaultEntitiesList()
        {
            var entitiesField = typeof(EntityLauncher).GetField("mSceneEntityComponents", 
                BindingFlags.NonPublic | BindingFlags.Instance);
            
            if (entitiesField != null)
            {
                var entities = entitiesField.GetValue(launcher) as List<Component>;
                if (entities != null)
                {
                    EditorGUILayout.LabelField($"实体数量: {entities.Count}", m_ValueStyle);
                    DrawEntitiesList(entities, entities);
                }
                else
                {
                    EditorGUILayout.LabelField("无法获取实体列表", EditorStyles.helpBox);
                }
            }
        }

        #endregion

        #region Runtime Entities List

        /// <summary>
        /// 绘制运行时实体列表
        /// </summary>
        private void DrawRuntimeEntitiesList()
        {
            var entitiesDict = Runtime.EntityManager.GetAllEntities();
            if (entitiesDict != null)
            {
                EditorGUILayout.LabelField($"运行时实体数量: {entitiesDict.Count}", m_ValueStyle);
                DrawEntityListItems(entitiesDict);
            }
            else
            {
                EditorGUILayout.LabelField("无法获取运行时实体列表", EditorStyles.helpBox);
            }
        }

        private void DrawEntityListItems(IEnumerable<object> entities)
        {
            int index = 0;
            foreach (var entity in entities)
            {
                if (entity != null)
                {
                    string label = GetEntityLabel(entity);
                    DrawEntityField(label, entity);
                    index++;
                }
            }
        }

        #endregion

        #region Scene Entities List

        /// <summary>
        /// 绘制场景中所有实体列表
        /// </summary>
        private void DrawSceneEntitiesList()
        {
            var sceneEntities = FindObjectsOfType<Component>().Where(c => c is IEntity).ToList();
            EditorGUILayout.LabelField($"场景中实体数量: {sceneEntities.Count}", m_ValueStyle);

            var entitiesField = typeof(EntityLauncher).GetField("mSceneEntityComponents",
                BindingFlags.NonPublic | BindingFlags.Instance);
            
            List<Component> addedEntities = null;
            if (entitiesField != null)
            {
                addedEntities = entitiesField.GetValue(launcher) as List<Component>;
            }

            for (int i = 0; i < sceneEntities.Count; i++)
            {
                var entity = sceneEntities[i];
                if (entity != null)
                {
                    GUILayout.BeginHorizontal();
                    string label = GetEntityLabel(entity);
                    DrawEntityField(label, entity);
                    DrawEntityAddButton(entity, addedEntities);
                    GUILayout.EndHorizontal();
                }
            }
        }

        #endregion

        #region Entity List Drawing

        /// <summary>
        /// 绘制实体列表
        /// </summary>
        /// <param name="entities">实体列表</param>
        private void DrawEntitiesList(List<Component> entities)
        {
            DrawEntitiesList(entities, null);
        }

        /// <summary>
        /// 绘制实体列表
        /// </summary>
        /// <param name="entities">实体列表</param>
        /// <param name="entityComponents">实体组件列表，用于删除操作</param>
        private void DrawEntitiesList(List<Component> entities, List<Component> entityComponents)
        {
            for (int i = 0; i < entities.Count; i++)
            {
                GUILayout.BeginHorizontal();
                DrawEntityListItem(entities, entityComponents, i);
                GUILayout.EndHorizontal();
            }
        }

        private void DrawEntityListItem(List<Component> entities, List<Component> entityComponents, int index)
        {
            // 检查对象是否有效
            bool isMissing = entities[index] != null && 
                            !EditorUtility.IsPersistent(entities[index]) && 
                            entities[index].gameObject == null;
            bool isNull = entities[index] == null;

            if (!isNull && !isMissing)
            {
                // 对象有效
                string label = GetEntityLabel(entities[index], index);
                DrawEntityField(label, entities[index]);
                //DrawMvcInfoIfApplicable(entities[index]);
            }
            else
            {
                // 对象已销毁或丢失
                string status = isMissing ? "Missing" : "Null";
                EditorGUILayout.LabelField($"[{index}] {status}", EditorStyles.helpBox);
            }

            // 如果传入了实体组件列表，则显示删除按钮
            if (entityComponents != null)
            {
                if (GUILayout.Button("Remove", GUILayout.Width(60)))
                {
                    RemoveEntityAt(index, entityComponents);
                }
            }
        }

        private string GetEntityLabel(object entity, int index = -1)
        {
            string prefix = index >= 0 ? $"[{index}]" : "";
            
            if (entity is Component component && component.gameObject != null)
            {
                return $"{prefix}[{component.gameObject.name}][{entity.GetType().Name}]";
            }
            
            return $"{prefix}[{entity.GetType().Name}]";
        }

        private void DrawEntityField(string label, object entity)
        {
            if (entity is Object entityObject)
            {
                EditorGUI.BeginDisabledGroup(true);
                EditorGUILayout.ObjectField(label, entityObject, typeof(Object), true, GUILayout.MinHeight(18));
                EditorGUI.EndDisabledGroup();
            }
            else
            {
                EditorGUILayout.LabelField(label, m_LabelStyle);
            }
        }

        private void DrawMvcInfoIfApplicable(Component entity)
        {
            // 检查是否是MvcEntity的任何泛型实例
            Type entityType = entity.GetType();
            Type baseMvcType = typeof(MvcEntity<>);
            bool isMvcEntity = IsSubclassOfRawGeneric(baseMvcType, entityType);
            
            if (isMvcEntity)
            {
                EditorGUI.indentLevel++;
                DrawMVCInfo(entity as Entity);
                EditorGUI.indentLevel--;
            }
        }

        private bool IsSubclassOfRawGeneric(Type generic, Type toCheck)
        {
            while (toCheck != null && toCheck != typeof(object))
            {
                var cur = toCheck.IsGenericType ? toCheck.GetGenericTypeDefinition() : toCheck;
                if (generic == cur)
                {
                    return true;
                }
                toCheck = toCheck.BaseType;
            }
            return false;
        }

        #endregion

        #region MVC Info

        /// <summary>
        /// 绘制MVC信息
        /// </summary>
        /// <param name="entity">SimpleSceneEntity实体</param>
        private void DrawMVCInfo(Entity entity)
        {
            // 获取entity的实际类型
            Type entityType = entity.GetType();

            // 获取泛型MvcEntity<>类型
            Type baseMvcType = typeof(MvcEntity<>);
            Type genericMvcType = baseMvcType.MakeGenericType(entityType);

            GUILayout.BeginVertical(m_BoxStyle);
            EditorGUILayout.LabelField("MVC 信息", m_SectionHeaderStyle);
            
            DrawMvcModels(entity, genericMvcType);
            DrawMvcViews(entity, genericMvcType);
            DrawMvcControllers(entity, genericMvcType);
            
            GUILayout.EndVertical();
        }

        private void DrawMvcModels(Entity entity, Type genericMvcType)
        {
            // 显示Model信息
            var modelsField = genericMvcType.GetField("mModels",
                BindingFlags.NonPublic | BindingFlags.Instance);
            
            if (modelsField != null)
            {
                var models = modelsField.GetValue(entity) as System.Collections.IList;
                if (models != null && models.Count > 0)
                {
                    EditorGUILayout.LabelField($"模型 ({models.Count}):", m_MiniLabelStyle);
                    EditorGUI.indentLevel++;
                    for (int i = 0; i < models.Count; i++)
                    {
                        var model = models[i];
                        if (model != null)
                        {
                            EditorGUILayout.LabelField(model.GetType().Name, m_MiniLabelStyle);
                        }
                    }
                    EditorGUI.indentLevel--;
                }
            }
        }

        private void DrawMvcViews(Entity entity, Type genericMvcType)
        {
            var viewsField = genericMvcType.GetField("mViews", BindingFlags.NonPublic | BindingFlags.Instance);
            if (viewsField != null)
            {
                var views = viewsField.GetValue(entity) as System.Collections.IList;
                if (views != null && views.Count > 0)
                {
                    EditorGUILayout.LabelField($"视图 ({views.Count}):", m_MiniLabelStyle);
                    EditorGUI.indentLevel++;
                    for (int i = 0; i < views.Count; i++)
                    {
                        var view = views[i];
                        if (view != null)
                        {
                            string label = GetEntityLabel(view);
                            if (view is Component viewObject)
                            {
                                EditorGUI.BeginDisabledGroup(true);
                                EditorGUILayout.ObjectField(label, viewObject, typeof(Component), true, GUILayout.MinHeight(18));
                                EditorGUI.EndDisabledGroup();
                            }
                            else
                            {
                                EditorGUILayout.LabelField(label, m_MiniLabelStyle);
                            }
                        }
                    }
                    EditorGUI.indentLevel--;
                }
            }
        }

        private void DrawMvcControllers(Entity entity, Type genericMvcType)
        {
            var controllersField = genericMvcType.GetField("mControllers", BindingFlags.NonPublic | BindingFlags.Instance);
            if (controllersField != null)
            {
                var controllers = controllersField.GetValue(entity) as System.Collections.IList;
                if (controllers != null && controllers.Count > 0)
                {
                    EditorGUILayout.LabelField($"控制器 ({controllers.Count}):", m_MiniLabelStyle);
                    EditorGUI.indentLevel++;
                    for (int i = 0; i < controllers.Count; i++)
                    {
                        var controller = controllers[i];
                        if (controller != null)
                        {
                            EditorGUILayout.LabelField(controller.GetType().Name, m_MiniLabelStyle);
                        }
                    }
                    EditorGUI.indentLevel--;
                }
            }
        }

        #endregion

        #region Action Buttons

        /// <summary>
        /// 绘制操作按钮
        /// </summary>
        private void DrawActionButtons()
        {
            DrawMainActionButtons();
            DrawBatchActionButtons();
        }

        private void DrawMainActionButtons()
        {
            GUILayout.BeginVertical(m_BoxStyle);
            EditorGUILayout.LabelField("操作", m_SectionHeaderStyle);
            
            GUILayout.BeginHorizontal();
            GUILayout.Space(10); // 子元素内边距
            
            if (Application.isPlaying)
            {
                if (GUILayout.Button("手动初始化", m_ButtonStyle, GUILayout.MinHeight(24)))
                {
                    var manualInitMethod = typeof(EntityLauncher).GetMethod("ManualInitialize",
                        BindingFlags.Public | BindingFlags.Instance);
                    if (manualInitMethod != null)
                    {
                        manualInitMethod.Invoke(launcher, null);
                    }
                }
            }

            if (GUILayout.Button("刷新", m_ButtonStyle, GUILayout.MinHeight(24)))
            {
                Repaint();
            }
            
            GUILayout.Space(10);
            GUILayout.EndHorizontal();
            GUILayout.EndVertical();
        }

        private void DrawBatchActionButtons()
        {
            GUILayout.BeginVertical(m_BoxStyle);
            EditorGUILayout.LabelField("批量操作", m_SectionHeaderStyle);
            
            GUILayout.BeginHorizontal();
            GUILayout.Space(10); // 子元素内边距
            
            if (GUILayout.Button("添加所有场景实体", m_ButtonStyle, GUILayout.MinHeight(24)))
            {
                AddAllSceneEntities();
            }

            if (GUILayout.Button("删除所有场景实体", m_ButtonStyle, GUILayout.MinHeight(24)))
            {
                RemoveAllSceneEntities();
            }
            
            GUILayout.Space(10);
            GUILayout.EndHorizontal();
            GUILayout.EndVertical();
        }

        #endregion

        #region Entity Management

        private void DrawEntityAddButton(Component entity, List<Component> addedEntities)
        {
            if (addedEntities != null)
            {
                if (addedEntities.Contains(entity))
                {
                    EditorGUI.BeginDisabledGroup(true);
                    GUILayout.Button("Added", GUILayout.Width(60));
                    EditorGUI.EndDisabledGroup();
                }
                else
                {
                    if (GUILayout.Button("Add", GUILayout.Width(60)))
                    {
                        AddEntity(entity);
                    }
                }
            }
        }

        private void AddEntity(Component entity)
        {
            if (entity != null)
            {
                var entitiesField = typeof(EntityLauncher).GetField("mSceneEntityComponents",
                    BindingFlags.NonPublic | BindingFlags.Instance);
                
                if (entitiesField != null)
                {
                    var entities = entitiesField.GetValue(launcher) as List<Component>;
                    if (entities != null)
                    {
                        if (!entities.Contains(entity))
                        {
                            entities.Add(entity);
                            EditorUtility.SetDirty(target);
                            Debug.Log("Added entity, total count: " + entities.Count);
                        }
                        else
                        {
                            Debug.LogWarning("实体已在列表中");
                        }
                    }
                }
            }
        }

        private void RemoveEntity(Component entity)
        {
            if (entity != null)
            {
                var entitiesField = typeof(EntityLauncher).GetField("mSceneEntityComponents",
                    BindingFlags.NonPublic | BindingFlags.Instance);
                
                if (entitiesField != null)
                {
                    var entities = entitiesField.GetValue(launcher) as List<Component>;
                    if (entities != null)
                    {
                        if (entities.Contains(entity))
                        {
                            entities.Remove(entity);
                            EditorUtility.SetDirty(target);
                        }
                        else
                        {
                            Debug.LogWarning("实体不在列表中");
                        }
                    }
                }
            }
        }

        private void RemoveEntityAt(int index, List<Component> entityComponents)
        {
            if (entityComponents != null && index >= 0 && index < entityComponents.Count)
            {
                entityComponents.RemoveAt(index);
                EditorUtility.SetDirty(target);
            }
        }

        private void AddAllSceneEntities()
        {
            var sceneEntities = FindObjectsOfType<Component>().Where(c => c is IEntity).ToList();

            var entitiesField = typeof(EntityLauncher).GetField("mSceneEntityComponents",
                BindingFlags.NonPublic | BindingFlags.Instance);
            
            if (entitiesField != null)
            {
                var entities = entitiesField.GetValue(launcher) as List<Component>;
                if (entities != null)
                {
                    foreach (var entity in sceneEntities)
                    {
                        if (entity != null && !entities.Contains(entity))
                        {
                            entities.Add(entity);
                        }
                    }

                    EditorUtility.SetDirty(target);
                }
            }
        }

        private void RemoveAllSceneEntities()
        {
            var entitiesField = typeof(EntityLauncher).GetField("mSceneEntityComponents",
                BindingFlags.NonPublic | BindingFlags.Instance);
            
            if (entitiesField != null)
            {
                var entities = entitiesField.GetValue(launcher) as List<Component>;
                if (entities != null)
                {
                    entities.Clear();
                    EditorUtility.SetDirty(target);
                }
            }
        }

        #endregion
    }
}